/*
The main file for DDMCMC algorithm.
*/

#include "ddmcmc.h"

DDMCMC::DDMCMC() {
	/* Initialize a DDMCMC object. 
	 * Here we assume that the image is a color image, hence the scale(in ddmcmcSettings) is set to 3.0 by default.
	 */
	msClustering = NULL;
}

DDMCMC::~DDMCMC() {
}

void DDMCMC::segmentRegions() {

}

int DDMCMC::labelRegions() {
	segmentRegions();
	return 1;
}

void DDMCMC::generateProposal() {
	Mat mPartitionMaps[3];
	//cvtColor(mImg, mImg, CV_BGR2Luv);

	// Get edge proposal
	double dSigma[] = { 6.0, 4.0, 2.0 };
	edgePrcs = new DDMCMC_EdgePrcs(mImg);
	for (int k = 1; k <= 3; k++) {
		edgePrcs->segmentRegions(dSigma[k], mPartitionMaps[k]);
	}

	// Mean shift
	msClustering = new DDMCMC_MeanShiftClustering(mImg);
	msClustering->meanShiftSegmentation(1);

	return;
}

void DDMCMC::RunDDMCMCSegmentation(Raster_Color<uchar> &raster, Matrix<int> imageLabel[3], int num_label[], Raster<int> &image_init, const MCMC_SegSetting& setting1){
	Raster<int> matrix_temp;

	// set seed for random value generator
	ztu_srand(2000);

	/*
	pDocActive = this;
	((CIParsingApp*)AfxGetApp())->CreateEnergyWnd(this);
	((CIParsingApp*)AfxGetApp())->CreateGraphWnd(this, 0);
	((CIParsingApp*)AfxGetApp())->CreateGraphWnd(this, 1);

	((CMainFrame*)AfxGetMainWnd())->MDITile();
	*/

	// copy label image
	matrix_temp = image_init;

	// initialization
	if (pmap != NULL)
		pmap->LayerRegion()->Recover(matrix_temp);
	else
	{
		pmap = new MCMC_Map_2Layers();

		matrix_temp.RelabelReorder();
		matrix_temp.RelabelAndMergeTinyRegions(5);
		try
		{
			pmap->LayerRegion()->Build(matrix_temp);
		}
		catch (XPT_OutOfBound *pxpt)
		{
			delete pxpt;
			assert(false);
		}
		pmap->LayerRegion()->MergeSmallAtomicRegion();
	}


	/*
	char str_file_name[200];
	GetBmpFileName(str_file_name);

	// initialization
	pCtrProgressActive = ((CMainFrame*)AfxGetMainWnd())->m_pProgress;
	*/

	if (m_pmcmc_conductor != NULL)
		delete m_pmcmc_conductor;

	pmap->LayerRegion()->CreateTopologyRecords();
	// create group regions
	pmap->LayerRegion()->PutAllAtomicRegionsIntoGRegions();

	m_pmcmc_conductor = new MCMC_Conductor(*pmap, imageLabel, num_label, raster, ms_clustering, setting1, str_file_name);

	// show the gradient image
	Raster_Color<uchar> raster_syn;
	// segmenting
	m_pmcmc_conductor->GoNew(str_file_name, setting1);

	ShowSynthesizedImage(str_file_name);

	mx_labelmap.SetDimension(raster.rows(), raster.cols());
	pmap->LayerRegion()->LabelAtomicRegions(mx_labelmap);

	pmap->Synthesize(raster_syn, 1);
	((CMainFrame*)AfxGetMainWnd())->NewImageDoc(raster_syn);

	//save syn
	char str_name[200];
	sprintf(str_name, "%s_syn.bmp", str_file_name);
	SaveRaster2ImageFile(raster_syn, str_name);

	//show the final segmentation which consists of a lot of GRegions
	Raster_Color<uchar> ras_copy;
	Raster<int>			mx_boundary;

	ras_copy = raster;
	mx_boundary.SetDimension(raster.rows(), raster.cols());
	mx_boundary.InitValue(0);
	pmap->LayerRegion()->DrawRegions(mx_boundary);
	for (int j = 0; j < raster.rows(); j++){
		for (int i = 0; i<raster.cols(); i++){
			if (mx_boundary(j, i)>0)
			{
				ras_copy.R(j, i) = 255;
				ras_copy.G(j, i) = 0;
				ras_copy.B(j, i) = 0;
			}
			else
			{
				//				ras_copy.R(j,i) = 255;
				//				ras_copy.G(j,i) = 255;
				//				ras_copy.B(j,i) = 255;
			}
		}

	}

	/*
	((CMainFrame*)AfxGetMainWnd())->NewImageDoc(ras_copy);
	((CMainFrame*)AfxGetMainWnd())->MDITile();
	*/

	sprintf(str_name, "%s_bound.bmp", str_file_name);
	SaveRaster2ImageFile(ras_copy, str_name);

	CopyFromRasterColor(*m_pDib, raster);
}

bool DDMCMCSegmentation(Mat mInputimg) {
	DDMCMC ddmcmcSegmentation;

	ddmcmcSegmentation.mImg = mInputimg;
	ddmcmcSegmentation.generateProposal();

	RunDDMCMCSegmentation(image_color, partition_maps, num, image_init, setting);


	return false;
}